﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace StarUtils.Extension
{
    public static partial class StringExtension
    {
        private static readonly Regex DateRegex = new Regex("(\\d{4})-(\\d{1,2})-(\\d{1,2})");

        private static readonly Regex EmailRegex = new Regex("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*", RegexOptions.IgnoreCase);

        private static readonly Regex IpRegex = new Regex("^(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$");

        private static readonly Regex MobileRegex = new Regex("^1[0-9]{10}$");

        private static readonly Regex NumericRegex = new Regex("^[-]?[0-9]+(\\.[0-9]+)?$");

        private static readonly Regex PhoneRegex = new Regex("^(\\d{3,4}-?)?\\d{7,8}$");

        private static readonly Regex ZipcodeRegex = new Regex("^\\d{6}$");

        public static string Fmt(this string input, params object[] param)
        {
            if (input.IsNullOrWhiteSpace())
            {
                return null;
            }

            return string.Format(input, param);
        }

        public static string Format(this string inputStr, params object[] obj)
        {
            return string.Format(inputStr, obj);
        }

        public static bool IsChinese(this string str)
        {
            return Regex.IsMatch(str, "^[\\u4e00-\\u9fa5]+$");
        }

        public static bool IsDate(this string s)
        {
            return DateRegex.IsMatch(s);
        }

        public static bool IsEmail(this string s)
        {
            if (string.IsNullOrEmpty(s))
            {
                return false;
            }

            return EmailRegex.IsMatch(s);
        }

        public static bool IsIdCard(this string id, bool isValidCode = true)
        {
            if (!string.IsNullOrEmpty(id))
            {
                switch (id.Length)
                {
                    case 15:
                        return CheckIdCard15(id);
                    case 18:
                        return CheckIdCard18(id, isValidCode);
                }
            }

            return false;
        }

        public static bool IsImgFileName(this string fileName)
        {
            if (fileName.IndexOf(".", StringComparison.Ordinal) == -1)
            {
                return false;
            }

            string text = fileName.Trim().ToLower();
            string text2 = text.Substring(text.LastIndexOf(".", StringComparison.Ordinal));
            switch (text2)
            {
                default:
                    return text2 == ".gif";
                case ".png":
                case ".bmp":
                case ".jpg":
                case ".jpeg":
                    return true;
            }
        }

        public static bool IsIp(this string s)
        {
            return IpRegex.IsMatch(s);
        }

        public static bool IsMobile(this string s)
        {
            if (string.IsNullOrEmpty(s))
            {
                return false;
            }

            return MobileRegex.IsMatch(s);
        }

        public static bool IsNullOrEmpty(this string inputStr)
        {
            return string.IsNullOrEmpty(inputStr);
        }
        public static bool IsNotNullOrEmpty(this string inputStr)
        {
            return !string.IsNullOrEmpty(inputStr);
        }

        public static bool IsNullOrWhiteSpace(this string inputStr)
        {
            return string.IsNullOrWhiteSpace(inputStr);
        }
        public static bool IsNotNullOrWhiteSpace(this string inputStr)
        {
            return !string.IsNullOrWhiteSpace(inputStr);
        }

        public static bool IsNumeric(this string numericStr)
        {
            return NumericRegex.IsMatch(numericStr);
        }

        public static bool IsPhone(this string s)
        {
            if (string.IsNullOrEmpty(s))
            {
                return false;
            }

            return PhoneRegex.IsMatch(s);
        }

        public static bool IsZipCode(this string s)
        {
            if (!string.IsNullOrEmpty(s))
            {
                return ZipcodeRegex.IsMatch(s);
            }

            return true;
        }

        private static bool CheckIdCard15(string id)
        {
            if (!long.TryParse(id, out var result) || !((double)result >= Math.Pow(10.0, 14.0)))
            {
                return false;
            }

            if ("11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91".IndexOf(id.Remove(2), StringComparison.Ordinal) == -1)
            {
                return false;
            }

            DateTime result2;
            return DateTime.TryParse(id.Substring(6, 6).Insert(4, "-").Insert(2, "-"), out result2);
        }

        private static bool CheckIdCard18(string id, bool isValidCode = true)
        {
            if (!long.TryParse(id.Remove(17), out var result) || !((double)result >= Math.Pow(10.0, 16.0)) || !long.TryParse(id.Replace('x', '0').Replace('X', '0'), out result))
            {
                return false;
            }

            if ("11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91".IndexOf(id.Remove(2), StringComparison.Ordinal) == -1)
            {
                return false;
            }

            if (!DateTime.TryParse(id.Substring(6, 8).Insert(6, "-").Insert(4, "-"), out var _))
            {
                return false;
            }

            if (isValidCode)
            {
                string[] array = "1,0,x,9,8,7,6,5,4,3,2".Split(new char[1] { ',' });
                string[] array2 = "7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2".Split(new char[1] { ',' });
                char[] array3 = id.Remove(17).ToCharArray();
                int num = 0;
                for (int i = 0; i < 17; i++)
                {
                    num += int.Parse(array2[i]) * int.Parse(array3[i].ToString());
                }

                Math.DivRem(num, 11, out var result3);
                return array[result3] == id.Substring(17, 1).ToLower();
            }

            return true;
        }

        public static bool IsNull(this object obj)
        {
            return obj == null;
        }

        public static bool IsEmpty(this string value)
        {
            return string.IsNullOrWhiteSpace(value);
        }

        public static string SafeString(this object input)
        {
            if (input != null)
            {
                return input.ToString()!.Trim();
            }

            return string.Empty;
        }

        public static string Join<T>(IEnumerable<T> list, string quotes = "", string separator = ",")
        {
            if (list == null)
            {
                return string.Empty;
            }

            StringBuilder stringBuilder = new StringBuilder();
            foreach (T item in list)
            {
                stringBuilder.AppendFormat("{0}{1}{0}{2}", quotes, item, separator);
            }

            if (separator == "")
            {
                return stringBuilder.ToString();
            }

            return stringBuilder.ToString().TrimEnd(separator.ToCharArray());
        }

        public static List<string> ListString(string objectString)
        {
            List<string> result = new List<string>();
            if (!objectString.IsEmpty())
            {
                result = new List<string>(objectString.Split(new string[1] { "," }, StringSplitOptions.RemoveEmptyEntries));
            }

            return result;
        }

        public static string MidStrEx(this string sourse, string startstr, string endstr)
        {
            if (sourse.IsNullOrWhiteSpace())
            {
                return string.Empty;
            }

            string empty = string.Empty;
            try
            {
                int num = sourse.IndexOf(startstr);
                if (num == -1)
                {
                    return empty;
                }

                string text = sourse.Substring(num + startstr.Length);
                int num2 = text.IndexOf(endstr);
                if (num2 == -1)
                {
                    return empty;
                }

                return text.Remove(num2);
            }
            catch
            {
                return string.Empty;
            }
        }
    }
}
